package com.service.user.impl;

import com.dao.GoodsDao;
import com.dao.OthersDao;
import com.dao.ReportDao;
import com.entity.GoodReport;
import com.entity.Goods;
import com.entity.GoodsBasic;
import com.entity.Notice;
import com.service.user.GoodService;
import com.service.user.NoticeService;
import com.utils.FileUploadUtil;
import com.utils.SqlSessionGetter;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 提供和商品相关的功能实现
 *
 * 
 */
@Service
public class GoodServiceImpl implements GoodService {

  @Autowired NoticeService noticeService;

  @Override
  public List<Goods> getGoods(
      int pageSize,
      int pageIndex,
      String goodId,
      int status,
      Float fromPrice,
      Float toPrice,
      Integer categoryId,
      String name,
      String userId,
      Date fromUpdateTime,
      Date toUpdateTime,
      Date fromPublicDate,
      Date toPublicDate,
      String author,
      String appearance,
      String pressHorse,
      String sortWay) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao goodsDao = session.getMapper(GoodsDao.class);
    List<Goods> goods =
        goodsDao.selectGoods(
            pageSize * pageIndex,
            pageSize,
            goodId,
            status,
            fromPrice,
            toPrice,
            categoryId,
            name,
            userId,
            fromUpdateTime,
            toUpdateTime,
            fromPublicDate,
            toPublicDate,
            author,
            appearance,
            pressHorse,
            sortWay);
    session.close();
    return goods;
  }

  /**
   * 走马灯推荐书籍编号及其图片
   *
   * @param userId 用户编号
   * @param count 获取的数量
   * @return 对应数量的推荐商品
   */
  @Override
  public List<Map<String, String>> getMostPopular(String userId, int count) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    List<Map<String, String>> idImgs = dao.getMostPopular(count);
    session.close();
    return idImgs;
  }

  /**
   * 获取主页分类展示书籍的列表
   *
   * @param categoryNum 获取的种类数目
   * @param goodsNum 每个类别的商品数量
   * @return 分类展示书籍的列表
   */
  // TODO 这里关于书籍列表的还没处理好
  @Override
  public List<Map<String, Object>> getShowGoods(int categoryNum, int goodsNum) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    OthersDao othersdao = session.getMapper(OthersDao.class);
    List<Map<String, Object>> bases = othersdao.selectBasicCategory();
    List<Map<String, Object>> typeGoods = new ArrayList<>(categoryNum);
    int typeCount = 0;
    GoodsDao goodsDao = session.getMapper(GoodsDao.class);
    for (Map<String, Object> type : bases) {
      // 该类别最受欢迎的书籍
      List<GoodsBasic> goods =
          goodsDao.selectCategoryPopularGoodsBasic((Integer) type.get("id"), goodsNum);
      type.put("goods", goods);
      typeGoods.add(type);
      if (++typeCount == categoryNum) {
        break;
      }
    }
    session.close();
    return typeGoods;
  }

  /**
   * 获取书籍详情
   *
   * @param userId 用户编号
   * @param goodId 商品编号
   * @return 商品详情
   */
  @Override
  public Goods getGoodDetail(String userId, String goodId, int minStatus) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao goodsDao = session.getMapper(GoodsDao.class);

    // 查询商品
    Goods good = goodsDao.selectGoodById(goodId, minStatus);

    session.close();
    return good;
  }

  /**
   * 更新浏览次数(sql语句里不是自己的商品才会更新浏览次数）
   *
   * @param userId 用户编号
   * @param goodId 商品编号
   * @return 更新成功返回1，失败返回0
   */
  @Override
  public int updateGoodVisit(String userId, String goodId) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao goodsDao = session.getMapper(GoodsDao.class);
    int ret = goodsDao.updateViewCount(userId, goodId);
    session.commit();
    session.close();
    return ret;
  }

  /**
   * 获取商品的基本信息
   *
   * @param goodId 商品编号
   * @param minStatus 最小的状态(只能查询到比该状态大或等于该状态的商品信息)
   * @return 商品的基本信息
   */
  @Override
  public GoodsBasic getGoodsBasicById(String goodId, int minStatus) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao goodsDao = session.getMapper(GoodsDao.class);
    GoodsBasic gb = goodsDao.selectGoodBasicById(goodId, minStatus);
    session.close();
    return gb;
  }

  // TODO 商品搜索的优化

  /**
   * 获取卖家信息
   *
   * @param goodId 商品编号
   * @return 卖家昵称nickname和用户编号userId
   */
  @Override
  public Map<String, String> getSeller(String goodId) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao goodsDao = session.getMapper(GoodsDao.class);
    Map<String, String> seller = goodsDao.selectSeller(goodId);
    session.close();
    return seller;
  }

  /**
   * 根据关键字搜索
   *
   * @param keywords 关键字
   * @param sortBy sortBy 0->综合排序，1->价格，2->品相，3->卖家评分
   * @param sortWay sortWay 升序asc/或降序desc
   * @param pageSize 页大小
   * @param pageIndex 页索引
   * @return 指定页的商品搜索结果
   */
  @Override
  public List<GoodsBasic> searchGoods(
      String keywords, int sortBy, String sortWay, int pageSize, int pageIndex) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao goodsDao = session.getMapper(GoodsDao.class);
    List<GoodsBasic> gbl =
        goodsDao.searchGoods(
            "%" + keywords + "%",
            GoodsDao.ORDER_BY[sortBy],
            sortWay,
            pageSize * pageIndex,
            pageSize);
    session.close();
    return gbl;
  }

  /**
   * 获取相关书籍
   *
   * @param goodId 书籍编号
   * @return 相关书籍列表
   */
  @Override
  public List<GoodsBasic> getRelevantGoods(String goodId) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    List<GoodsBasic> gbl = dao.selectRelevantGoods(goodId);
    session.close();
    return gbl;
  }
  @Override
  public List<GoodsBasic> getAuthorGoods(String goodId) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    List<GoodsBasic> gbl = dao.selectAuthorGoods(goodId);
    session.close();
    return gbl;
  }
  @Override
  public List<GoodsBasic> getAlsoViewGoods(String goodId, int count, String userId) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    List<GoodsBasic> gbl = dao.selectAlsoViewGoods(goodId, count, userId);
    session.close();
    return gbl;
  }

  @Override
  public List<Map<String, Object>> getRelevantCategories(String goodId) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    List<Map<String, Object>> relevantCategories = dao.selectRelevantCategories(goodId);
    session.close();
    return relevantCategories;
  }

  @Override
  public int reportGood(
      String userId,
      String goodId,
      String type,
      String reason,
      MultipartFile pic1,
      MultipartFile pic2,
      MultipartFile pic3) {
    String rpId = UUID.randomUUID().toString().replace("-", "");
    String pic1URL =
        FileUploadUtil.uploadFile(
            pic1, rpId + "1", FileUploadUtil.GOOD_REPORT_SUBDIR, FileUploadUtil.IMAGE_SUFFIX);
    String pic2URL =
        FileUploadUtil.uploadFile(
            pic2, rpId + "2", FileUploadUtil.GOOD_REPORT_SUBDIR, FileUploadUtil.IMAGE_SUFFIX);
    String pic3URL =
        FileUploadUtil.uploadFile(
            pic3, rpId + "3", FileUploadUtil.GOOD_REPORT_SUBDIR, FileUploadUtil.IMAGE_SUFFIX);
    SqlSession session = SqlSessionGetter.getSqlSession();
    ReportDao dao = session.getMapper(ReportDao.class);
    int row = dao.insertAGoodReport(rpId, userId, goodId, type, reason, pic1URL, pic2URL, pic3URL);
    session.commit();
    GoodReport gr = dao.selectGoodReportById(rpId);
    session.close();
    // 添加通知
    noticeService.addNotice(
        userId,
        Notice.GOOD_REPORT,
        null,
        1,
        goodId,
        gr.getGoodName(),
        type,
        reason,
        pic1URL,
        pic2URL,
        pic3URL,
        gr.getReportTime());
    return row;
  }

  /**
   * 修改商品状态
   *
   * @param userId 用户编号
   * @param goodId 商品编号
   * @param newStatus 新的状态
   * @return 修改成功返回1，否则返回0
   */
  @Override
  public int chGoodStatus(String userId, String goodId, int newStatus) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    int ret = dao.updateGoodStatus(userId, goodId, newStatus);
    session.commit();
    session.close();
    return ret;
  }

  @Override
  public int chUserAllGoodsStatus(String userId, int newStatus) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    int ret = dao.updateUserAllGoodsStatus(userId, newStatus);
    session.commit();
    session.close();
    return ret;
  }

  /**
   * 删除商品更多图片或视频
   *
   * @param userId 用户编号
   * @param goodId 商品编号
   * @param fileURL 要删除的文件的url
   * @return 删除成功返回1，否则返回0
   */
  @Override
  public int delGoodMoreFile(String userId, String goodId, String fileURL) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    String sellerId = dao.selectSellerId(goodId);
    if (!sellerId.equals(userId)) {
      return 0;
    }
    FileUploadUtil.delFile(fileURL);
    int ret = dao.deleteMoreFileURL(goodId, fileURL);
    session.commit();
    session.close();
    return ret;
  }

  /**
   * 删除商品
   *
   * @param userId 用户编号
   * @param goodId 商品编号
   * @return 删除成功返回-1，否则返回0
   */
  @Override
  public int delGood(String userId, String goodId) {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    // 删除该商品的所有其他图片
    dao.deleteAllMoreFileURL(goodId);
    int ret = dao.updateGoodStatus(userId, goodId, GoodsDao.DELETE);
    session.commit();
    session.close();
    return ret;
  }

  @Override
  public List<Map<String, Object>> getTypeGoodCount() {
    SqlSession session = SqlSessionGetter.getSqlSession();
    GoodsDao dao = session.getMapper(GoodsDao.class);
    List<Map<String, Object>> typeGoodCount = dao.selectTypeGoodCount();
    session.commit();
    session.close();
    return typeGoodCount;
  }
}
